#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
'''
@File    :   icvd.py
@Time    :   2020/11/26
@Author  :   wenke wang
@Version :   1.0
@Desc    :   ICVD10年风险评估模型
'''

# here put the import lib
import sys, os, json
from decimal import Decimal
from icvd_eval_param import IcvdEvalParam

def get_default_settings():
    """
    获取默认的评分配置
    """
    default_setting = None

    setting_path = os.path.join(sys.path[0], "icvd_score_setting.json")
    with open(setting_path, "r", encoding="utf-8") as fp:
        default_setting = json.load(fp)
    
    return default_setting

def evaluate(param, score_settings = None):
    """
    ICVD10年风险评估模型
    """
    if not score_settings:
        score_settings = get_default_settings()
    
    score_settings = score_settings[param.gender]


    total_score = 0

    # 年龄得分
    age_setting = score_settings["age"]
    score_start = age_setting["score_start"]
    f_score = lambda x, i, s: x + i * s    
    # age_list = [{"low": 35, "high": 39, "score": 0}, {"low": 40, "high": 44, "score": 1},...]
    age_list = [ { "low": s + i, "high": s + i + age_setting["age_step"], "score": f_score(age_setting["score_start"], i, age_setting["score_step"]) } for i, s in enumerate(range(age_setting["low"], age_setting["high"], age_setting["age_step"]))]    
    total_score = total_score + [a["score"] for a in age_list if a["low"] <= param.age and a["high"] >= param.age][0]
    
    # 收缩压得分
    sbp_settings = score_settings["sbp"]
    total_score = total_score + [s["score"] for s in sbp_settings if s["low"] <= param.sbp and s["high"] >= param.sbp][0]
    
    # BMI得分
    bmi_settings = score_settings["bmi"] 
    total_score = total_score + [s["score"] for s in bmi_settings if Decimal(str(s["low"])) <= param.bmi and Decimal(str(s["high"])) >= param.bmi][0]

    # TC得分
    tc_settings = score_settings["tc"]
    total_score = total_score + [s["score"] for s in tc_settings if Decimal(str(s["low"])) <= param.tc and Decimal(str(s["high"])) >= param.tc][0]

    # 吸烟得分
    smoking_settings = score_settings["smoking"]
    total_score = total_score + [s["score"] for s in smoking_settings if s["val"] == param.smoking][0]

    # 糖尿病得分
    dm_settings = score_settings["dm"]
    total_score = total_score + [s["score"] for s in dm_settings if s["val"] == param.dm][0]

    # 绝对危险
    score_low = score_settings["risk_absolute"][0]
    score_high = score_settings["risk_absolute"][-1]
    if total_score <= score_low["score"]:
        risk_absolute = score_low
    elif total_score >= score_high["score"]:
        risk_absolute = score_high
    else:
        risk_absolute = [a for a in score_settings["risk_absolute"] if a["score"] == total_score]
        # risk_absolute = { "score": total_score, "risk_absolute": risk_absolute[0] if len(risk_absolute) > 0 else None }
        if not risk_absolute:
            raise ValueError("could not evaluate the absolute risk.")
        risk_absolute = risk_absolute[0]

    # 同龄同性别人群平均风险和最低风险
    risk_relative = [(r["risk_mean"], r["risk_min"]) for r in score_settings["risk_relative"] if r["age_low"] <= param.age and r["age_high"] >= param.age]
    if not risk_relative:
        return { "score": total_score, "risk_absolute": "%s%2.1f%%" % (risk_absolute["symbol"], risk_absolute["percent"]) }
    risk_relative = risk_relative[0]

    zero = Decimal("0.0")
    precision = Decimal("0.0")
    abs_percent = Decimal(str(risk_absolute["percent"]))
    mean_percent = Decimal(str(risk_relative[0]))
    # 比同龄同性别一般人群绝对风险净增(或净减)百分比
    risk_mean_diff = abs_percent - mean_percent
    if risk_mean_diff > zero:
        risk_mean_flag = "H" # 净增
    elif risk_mean_diff < zero:
        risk_mean_flag = "L" # 净减
    else:
        risk_mean_flag = ""
    # 未来10年ICVD疾病发生相对风险是一般人群的n倍
    risk_mean_multi = Decimal(abs_percent / mean_percent).quantize(precision)

    # 比同龄同性别低危人群绝对风险净增(或净减)百分比
    min_percent = Decimal(str(risk_relative[1]))
    risk_min_diff = abs_percent - min_percent
    if risk_min_diff > zero:
        risk_min_flag = "H" # 净增
    elif risk_min_diff < zero:
        risk_min_flag = "L" # 净减
    else:
        risk_min_flag = ""
    # 未来10年ICVD疾病发生相对风险是低危人群的n倍
    risk_min_multi = Decimal(abs_percent / min_percent).quantize(precision)
    
    return { 
        "score": total_score, 
        "risk_absolute": "%s%2.1f%%" % (risk_absolute["symbol"], risk_absolute["percent"]), 
        "risk_mean": {
            "diff": str(risk_mean_diff),
            "flag": risk_mean_flag,
            "multi": str(risk_mean_multi)
        },
        "risk_min": {
            "diff": str(risk_min_diff),
            "flag": risk_min_flag,
            "multi": str(risk_min_multi)
        }
    }

if __name__ == "__main__":
    param = IcvdEvalParam(57, 'M', 170, 55, 0, 1, 169, 280)
    res = evaluate(param)
    print(res)
    


    

    
